use core::ops::Add;
use core::ops::Sub;

use crate::vm::pgtable::page;

use super::paddr::Paddr;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]

pub struct Pfnaddr(usize);

impl From<usize> for Pfnaddr {
    fn from(value: usize) -> Self {
        Self(value)
    }
}

impl From<Paddr> for Pfnaddr {
    fn from(value: Paddr) -> Self {
        Pfnaddr::from(value.to_value())
    }
}

impl Add<usize> for Pfnaddr {
    type Output = Pfnaddr;
    fn add(self, rhs: usize) -> Self::Output {
        Pfnaddr::from(self.0 + rhs)
    }
}

impl Sub<usize> for Pfnaddr {
    type Output = Pfnaddr;
    fn sub(self, rhs: usize) -> Self::Output {
        Pfnaddr::from(self.0 - rhs)
    }
}

impl Pfnaddr {
    pub const fn to_value(&self) -> usize {
        self.0
    }

    pub fn to_paddr(&self) -> Paddr {
        Paddr::from(self.0 << page::PAGE_SHIFT)
    }
}
